Conversation
Dashboard filter dropdowns now narrow one another: selecting a value in one filter constrains the options shown by the others to values that co-occur with the current selection (e.g. picking a cluster limits the namespace dropdown to namespaces in that cluster). Applies to both manually-created dashboards and the bundled Kubernetes page (which also honors its free-text search). A filter never constrains its own options, so multi-select within a filter still works. HDX-4462
🦋 Changeset detectedLatest commit: 8d896bd The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🔵 Tier 2 — Low RiskSmall, isolated change with no API route or data model modifications. Why this tier:
Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns. Stats
|
E2E Test Results✅ All tests passed • 198 passed • 3 skipped • 1315s
Tests ran across 4 shards in parallel. |
Deep Review✅ No critical issues found. The faceting design is sound — constraints are AND-combined in 🟡 P2 — recommended
🔵 P3 nitpicks (6)
Reviewers (8): correctness, adversarial, testing, maintainability, kieran-typescript, julik-frontend-races, performance, project-standards. Testing gaps:
|
Greptile SummaryAdds an opt-in "link filters" toggle to the dashboard and Kubernetes filter bars. When enabled, each dropdown's selectable values are narrowed by the other current selections via a single
Confidence Score: 5/5Safe to merge. The feature is opt-in and off by default, so the unconstrained path is unchanged for all existing users. The two-level query design (MV routing in the outer query, value fetching in the inner) is well-structured and correctly keyed for React Query caching. The exclude-self faceting logic, the stripFieldClause utility, and the MV covering-dimension check are all backed by thorough unit tests. The two observations are about resilience and API footguns that don't affect any current call site. packages/common-utils/src/core/materializedViews.ts and metadata.ts contain the new server-side logic worth a second look during future changes. Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as FilterLinkToggle / Dropdown
participant DFV as useDashboardFilterValues
participant OKV as useOptimizedKeyValuesCalls
participant OFKV as optimizeFacetedKeyValuesConfig
participant Meta as Metadata.getKeyValues
UI->>DFV: "filterValues (when linked=true)"
DFV->>OKV: filters + filterValues
OKV->>OKV: conditionByFilterId (exclude-self, same source)
alt "any keyCondition != null (faceted)"
OKV->>OFKV: chartConfig + keys + keyConditions
OFKV->>OFKV: find covering MVs (all keys are dimensions)
OFKV-->>OKV: facetedConfig (MV or raw table)
OKV-->>DFV: EnrichedCall with facetedConfig + keyConditions
DFV->>Meta: "getKeyValues(facetedConfig, keyConditions, disableRowLimit=true)"
Meta-->>DFV: groupUniqArrayIf results per key
else no conditions (unlinked / nothing selected)
OKV->>OKV: optimizeGetKeyValuesCalls (MV rollup per key)
OKV-->>DFV: EnrichedCall[]
DFV->>Meta: "getKeyValues(chartConfig, disableRowLimit=true)"
Meta-->>DFV: groupUniqArray results per key
end
DFV-->>UI: values per filterId
Reviews (9): Last reviewed commit: "perf(dashboards): route faceted filter s..." | Re-trigger Greptile |
stripFieldClause and extractValueFromSearchQuery interpolated the attribute name straight into a RegExp. Escape it (lodash escapeRegExp) so dots match literally instead of as wildcards, and metacharacters like '(' or '[' in a resource-attribute expression can't throw a SyntaxError.
Memoize the five FilterSelect chart configs in a single useMemo (keyed on searchQuery, dateRange, metricSource) so they keep a stable identity across re-renders unrelated to the filters, avoiding repeated React Query key serialization. (useCallback on the builder wouldn't help: calling it still mints a new object per render.)
Add tests covering literal-dot matching and the metacharacter case.
|
Outstanding discussions:
|
Add a bidirectional-arrow toggle at the end of the dashboard and Kubernetes filter bars that opts into linked (faceted) filter values, off by default. When linked, each dropdown's values are narrowed by the other selections (and the K8s free-text search) and fetched lazily only when the dropdown is opened, bounding the cost of contingent value lookups that can't use per-key rollups. Search-page filters are untouched.
| const { data: sources, isLoading: isLoadingSources } = useSources(); | ||
|
|
||
| // Group filters by (source, metricType, where, whereLanguage) so that we can test each group for MV compatibility separately. | ||
| // Faceted filtering: each filter's selectable values are narrowed by the |
There was a problem hiding this comment.
One perf-related downside to this is that it makes it less likely that filters can leverage materialized views (since any selected filters being applied to the filter must be a dimension in the materialized view). Fine at reasonable scales, less so at scales that actually require MVs.
Maybe providing the option like we do on the search page is the right move, as Alex (I think?) suggested
| // single key-values query; each selected filter (which omits its own | ||
| // expression) splits into its own query. |
There was a problem hiding this comment.
Another potential idea, to reduce the number of queries / performance impact, could be to do what we do for source filters:
SELECT
groupUniqArrayIf(columnA, conditions on columnB),
groupUniqArrayIf(columnB, conditions on columnA)
FROM ...
There was a problem hiding this comment.
Also - there might be some additional code re-use opportunities now between dashboard filters and source filters.
There was a problem hiding this comment.
Addressed the first suggestion and will ticket the re-use potential.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
Replace the lazy-on-open fetching with a single scan: getKeyValues/getKeyValuesWithMVs accept per-key conditions and emit groupUniqArrayIf(key, cond), so all of a source's faceted value lists resolve in one query instead of one per filter. Drops the open-tracking/activeFilterIds machinery (lazy-on-open was poor UX); the opt-in link toggle stays. K8s now also batches its 5 dropdowns into a single query. Unconstrained lookups still use the MV optimizer.
filtersToQuery returns the Filter union, whose sql_ast member has no `condition`; use a 'condition' in f guard so the faceting predicate build type-checks. (A stale common-utils dist / nx cache masked this locally.)
…ed view Addresses review feedback: the single-pass groupUniqArrayIf scan previously always hit the raw table when linked. Add optimizeFacetedKeyValuesConfig — when one MV's dimensions cover every filter column, EXPLAIN-validate the faceted query against it and use it (cheapest row estimate), else fall back to raw. Wired into the dashboard hook and getKeyValuesWithMVs. Keeps the single-query win and restores MV leverage at scale; off-by-default unchanged.

Summary
Adds opt-in linked (faceted) filter values to the dashboard and Kubernetes filter bars. A bidirectional-arrow "link filters" toggle at the end of each bar (off by default) turns on filter-awareness: each dropdown then only shows values that co-occur with the other current selections — e.g. picking a
clusternarrows thenamespacedropdown to namespaces in that cluster (the K8s bar also factors in the free-text search). A filter never constrains its own options, so multi-select still works. When linked, a dropdown's narrowed values are fetched lazily only when it is opened, which bounds the cost of these contingent lookups — they can't be served from the cheap per-key rollups and are far more expensive at scale, so they stay opt-in and off by default. Search-page filters are intentionally untouched. Addresses HDX-4462.Screenshots or video
Kubernetes-Dashboard-.-ClickStack.webm
How to test on Vercel preview
Preview routes: /kubernetes
Steps:
/kubernetes.ClusterandNamespacedropdowns (cluster-filter-select,namespace-filter-select) and the link-filters toggle (k8s-filters-link-toggle).References